//
//  Api.m
//  KangarooDoctor
//
//  Created by 廖罡 on 2024/1/12.
//

#import "Api.h"


NSTimeInterval defaultTimeoutInterval = 30;

@implementation Api

+(instancetype)shared
{
    static Api *api = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        api = [Api new];
    });
    return api;
}

-(void)postAtPath:(NSString*)path callback:(ApiCallback)callback
{
    [self method:@"POST"
          path:path
           param:nil
          header:nil
        callback:callback];
}

-(void)postAtPath:(NSString*)path param:(NSDictionary*)param callback:(ApiCallback)callback
{
    [self method:@"POST"
          path:path
           param:param
          header:nil
        callback:callback];
}

-(void)postAtPath:(NSString*)path param:(NSDictionary*)param header:(NSDictionary<NSString*, NSString*>*)header callback:(ApiCallback)callback
{
    [self method:@"POST"
          path:path
           param:param
          header:header
        callback:callback];
}


//============================================================================


-(void)putAtPath:(NSString*)path callback:(ApiCallback)callback {
    [self method:@"PUT"
          path:path
           param:nil
          header:nil
        callback:callback];
}
-(void)putAtPath:(NSString*)path param:(NSDictionary*)param callback:(ApiCallback)callback {
    [self method:@"PUT"
          path:path
           param:param
          header:nil
        callback:callback];
}
-(void)putAtPath:(NSString*)path param:(NSDictionary*)param header:(NSDictionary<NSString*, NSString*>*)header callback:(ApiCallback)callback
{
    [self method:@"PUT"
          path:path
           param:param
          header:header
        callback:callback];
}


//============================================================================



-(void)deleteAtPath:(NSString*)path callback:(ApiCallback)callback
{
    [self method:@"DELETE"
          path:path
           param:nil
          header:nil
        callback:callback];
}

-(void)deleteAtPath:(NSString*)path param:(NSDictionary*)param callback:(ApiCallback)callback
{
    [self method:@"DELETE"
          path:path
           param:param
          header:nil
        callback:callback];
}
-(void)deleteAtPath:(NSString*)path param:(NSDictionary*)param header:(NSDictionary<NSString*, NSString*>*)header callback:(ApiCallback)callback {
    [self method:@"DELETE"
          path:path
           param:param
          header:header
        callback:callback];
}

//============================================================================
-(void)getAtPath:(NSString*)path callback:(ApiCallback)callback
{
    [self method:@"GET"
          path:path
           param:nil
          header:nil
        callback:callback];
}

-(void) getAtPath:(NSString*)path param:(NSDictionary*)param callback:(ApiCallback)callback
{
    [self method:@"GET" 
          path:path
           param:param
          header:nil
        callback:callback];
}

-(void)getAtPath:(NSString*)path param:(NSDictionary*)param header:(NSDictionary<NSString*, NSString*>*)header callback:(ApiCallback)callback
{
    [self method:@"GET"
          path:path
           param:param
          header:header
        callback:callback];
}

-(void)method:(NSString*)method
       path:(NSString*)path
        param:(NSDictionary*)param
       header:(NSDictionary<NSString*, NSString*>*)header
     callback:(ApiCallback)callback
{
    if ([path containsString:@"/oss/"]) {
    }else{
        path = [NSString stringWithFormat:@"/appservice%@", path];
    }
    
    NSURLComponents *c = [NSURLComponents new];
    c.scheme = @"http";
    c.host = self.host;
    c.port = self.port;
    c.path = path;
    //    c.queryItems = @[q];
    
    NSLog(@"url: %@",c.URL);
    
    NSData *httpBody = nil;
    
    if (param != nil) {
        if ([method isEqualToString: @"GET"] || [method isEqualToString: @"DELETE"]) {
            
            NSMutableArray<NSURLQueryItem *> *queryItems = [NSMutableArray new];
            for (NSString *key in param) {
                [queryItems addObject:[NSURLQueryItem queryItemWithName:key value:param[key]]];
            }
            c.queryItems  = queryItems;
        }else{
            NSError *err;
            NSData *paramData = [NSJSONSerialization dataWithJSONObject:param options:0 error:&err];
            if (err != nil) {
                callback(nil, err.description);
                return;
            }
            httpBody = paramData;
        }
    }
    
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:c.URL];
    request.timeoutInterval = defaultTimeoutInterval;
    request.HTTPMethod = method;
    
    if ([method isEqualToString:@"POST"] ||
        [method isEqualToString:@"PUT"] ) {
        [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    }
    
    for (NSString *key in header) {
        NSString *value = header[key];
        [request setValue:value forHTTPHeaderField:key];
    }
    
    if (httpBody) {
        request.HTTPBody = httpBody;
    }
    
    [[[self URLSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        NSLog(@"result: %@, %@, %@", data, response, error);
        
        dispatch_async(dispatch_get_main_queue(), ^{
            if (error) {
                callback(nil, error.description);
            }else{
                NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
                NSNumber *code = json[@"code"];
                
                NSLog(@"code: %@", code);
                if (code.intValue == 200) {
                    NSLog(@"data: %@", data);
                    callback(json[@"data"], nil);
                }else{
                    
                    NSString *msg = json[@"msg"];
                    NSLog(@"msg: %@", msg);
                    callback(nil, [NSString stringWithFormat:@"%@",msg]);
                }
            }
        });
        
    }] resume];
}

-(NSDictionary*)connectionProxyDictionary
{
    NSString* host = @"192.168.5.4";
//    NSString* host = @"127.0.0.1";
    
    NSNumber* port = [NSNumber numberWithInt: 8888];
    return @{
        @"HTTPEnable":@(1),
        (NSString*)kCFStreamPropertyHTTPProxyHost: host,
        (NSString*)kCFStreamPropertyHTTPProxyPort: port
    };
}

-(NSURLSession*)URLSession
{
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration ephemeralSessionConfiguration];
    config.HTTPShouldUsePipelining = YES;
    return [NSURLSession sessionWithConfiguration:config];
}

-(void)macClientTest
{
}

@end

